package com.mjf.scala.chapter05

/**
 * 高阶函数
 */
object Scala04_TestFunHigh {

  def main(args: Array[String]): Unit = {

    // 函数正常的调用和声明
/*    def foo(): Int = {
      println("foo...")
      10
    }

    var ff = foo  // 将函数执行结果赋值给ff
    println(ff)  // 10

    // 将函数作为值进行传递 语法：在函数名称后面+空格+下划线
    // 注意：将foo函数作为一个整体，赋值给f变量，f是函数类型() => Int
    val f: () => Int = foo _

    // 这个时候，f就是一个函数，如果想要运行f函数的话，必须加()
    println(f)  // <function0>,表示没有参数的函数类型
    println(f())  // 10

    // val f: () => Int = foo _ ，如果明确了变量的类型，那么空格和下划线可以省略
    var f1: () => Unit = foo
    println(f1)   // <function0>*/


    // 函数作为参数进行传递（大多数情况都是通过匿名函数的形式）
    // 定义函数calculator，该函数接收一个函数类型的参数f,f定义了对两个整数要进行什么样的操作
/*
    def calculator(a: Int, b: Int, op: (Int, Int) => Int): Int = {
      op(a, b)
    }

    // 定义函数f1，对两个整数完成加法运算
    def f1(a: Int, b: Int): Int = a + b

    println(calculator(10, 20, f1))
//    println(calculator(10, 20, (a: Int, b: Int) => a - b))
//    println(calculator(10, 20, (a, b) => a - b))
    println(calculator(10, 20, _ - _))    // 减法运算
*/


    // 函数可以作为返回值进行返回----函数的嵌套
    def f1(): ()=>Unit = {  // ()=>Unit为返回值类型，表示无参函数。可以直接省略自动推导
      def f2(): Unit = {
        println("函数f2被调用了")
      }
      // 将函数f2作为返回值返回给f1
      f2 _
    }

    val ff: () => Unit = f1();  // ff就是f2
    println(ff())   // 相当于f1()()


  }

}
